package com.juyu.miliao.api.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.juyu.miliao.api.dao.elasticsearch.FindDynamicElasticsearch;
import com.juyu.miliao.api.dao.elasticsearch.FindDynamicGiftInfoElasticsearch;
import com.juyu.miliao.api.dao.mysql.FindDynamicInfoDao;
import com.juyu.miliao.api.dao.mysql.FindDynamicSourceInfoDao;
import com.juyu.miliao.api.dao.redis.FindDynamicLikeDaoRedis;
import com.juyu.miliao.api.dao.redis.FollowRedisDao;
import com.juyu.miliao.api.domain.Appkey;
import com.juyu.miliao.api.domain.FindDynamicInfo;
import com.juyu.miliao.api.domain.FindDynamicSourceInfo;
import com.juyu.miliao.api.domain.dto.FindDynamicInfoDTO;
import com.juyu.miliao.api.domain.vo.*;
import com.juyu.miliao.api.util.RedisKeys;
import com.juyu.miliao.common.constant.SpendSystemMessage;
import com.juyu.miliao.common.exception.ConsumeRuntimeException;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;

/**
 * 发现社区
 * @author xuanqicheng
 */
@Service
public class FindService {
    /**
     * 资源动态类型默认值
     */
    public static final Integer FIND_DYNAMIC_SOURCE_TYPE_DEFAUL=0;
    /**
     * 资源动态类型为图片
     */
    public static final Integer FIND_DYNAMIC_SOURCE_TYPE_IMG = 1;
    /**
     * 资源动态类型为视频
     */
    public static final Integer FIND_DYNAMIC_SOURCE_TYPE_VOID = 2;

    public static final Integer FIND_DYNAMIC_CONTENT_LENGTH = 50;

    public static final String FIND_DYNAMIC_SHARE_KEY ="findDynamicShareUrl";

    @Autowired
    private FindDynamicInfoDao findDynamicInfoDao;

    @Autowired
    private FindDynamicSourceInfoDao findDynamicSourceInfoDao;

    @Autowired
    private FindDynamicElasticsearch findDynamicElasticsearch;

    @Autowired
    private FindDynamicGiftInfoElasticsearch findDynamicGiftInfoElasticsearch;

    @Autowired
    private FollowRedisDao followRedisDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private AppKeyService appKeyService;

    @Autowired
    private FindDynamicLikeDaoRedis findDynamicLikeDaoRedis;

    @Autowired
    private VestRobotMessageService vestRobotMessageService;


    /**
     * 添加发现动态
     * @param findDynamicInfoDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void addFindDynamicInfo(FindDynamicInfoDTO findDynamicInfoDTO) {

        FindDynamicInfo findDynamicInfo = new FindDynamicInfo();

        BeanUtils.copyProperties(findDynamicInfoDTO, findDynamicInfo);
        findDynamicInfo.setIsTop(0);
        findDynamicInfoDao.addFindDynamciInfo(findDynamicInfo);

        List<FindDynamicSourceInfo> findDynamicSourceInfos = new ArrayList<>();

        for(String url : findDynamicInfoDTO.getFindSourceUrls()){
            if(FIND_DYNAMIC_SOURCE_TYPE_DEFAUL.equals(findDynamicInfoDTO.getSourceType())
            ||FIND_DYNAMIC_SOURCE_TYPE_VOID.equals(findDynamicInfoDTO.getSourceType())){
                FindDynamicSourceInfo findDynamicSourceInfo = new FindDynamicSourceInfo()
                        .setFindSourceUrl(url)
                        .setFindId(findDynamicInfo.getFindId())
                        .setHeight(findDynamicInfoDTO.getHeight())
                        .setWidth(findDynamicInfoDTO.getWidth())
                        .setVideoImgUrl(findDynamicInfoDTO.getVideoImgUrl())
                        .setVideoTime(findDynamicInfoDTO.getVideoTime());
                findDynamicSourceInfos.add(findDynamicSourceInfo);
            }else if(FIND_DYNAMIC_SOURCE_TYPE_IMG.equals(findDynamicInfoDTO.getSourceType())){
                FindDynamicSourceInfo findDynamicSourceInfo = new FindDynamicSourceInfo()
                        .setFindSourceUrl(url)
                        .setFindId(findDynamicInfo.getFindId())
                        .setHeight(findDynamicInfoDTO.getHeight())
                        .setWidth(findDynamicInfoDTO.getWidth())
                        .setVideoImgUrl("")
                        .setVideoTime(0);
                findDynamicSourceInfos.add(findDynamicSourceInfo);
            }

        }

        findDynamicSourceInfoDao.addFindDynamicSourceInfos(findDynamicSourceInfos);

        sendSystemMessage(findDynamicInfo);

    }

    /**
     * 发送系统消息
     * @param findDynamicInfo
     */
    private void sendSystemMessage(FindDynamicInfo findDynamicInfo) {
        String message = SpendSystemMessage.FIND_DYNAMIC_AUDIT.getMessage();
        vestRobotMessageService.getSendMsg(findDynamicInfo.getUserId(),message);
    }

    /**
     * 检查dto
     * @param findDynamicInfoDTO
     */
    public void checkFindDynamicDTO(FindDynamicInfoDTO findDynamicInfoDTO) {
        if(findDynamicInfoDTO.getSourceType()!=null&&
                !FIND_DYNAMIC_SOURCE_TYPE_DEFAUL.equals(findDynamicInfoDTO.getSourceType())) {

            if(StringUtils.isBlank(findDynamicInfoDTO.getWidth())){
                throw  new ConsumeRuntimeException("图片宽不能为空");
            }
            if(StringUtils.isBlank(findDynamicInfoDTO.getHeight())){
                throw new ConsumeRuntimeException("图片宽不能为空");
            }

            if(findDynamicInfoDTO.getFindSourceUrls()==null||findDynamicInfoDTO.getFindSourceUrls().size()==0){
                throw new ConsumeRuntimeException("图片不能为空");
            }

            if (FIND_DYNAMIC_SOURCE_TYPE_IMG.equals(findDynamicInfoDTO.getSourceType())) {

                if (findDynamicInfoDTO.getFindSourceUrls().size() > 5) {
                    throw new ConsumeRuntimeException("图片最多为5张");
                }
            } else if (FIND_DYNAMIC_SOURCE_TYPE_VOID.equals(findDynamicInfoDTO.getSourceType())) {
                if(StringUtils.isBlank(findDynamicInfoDTO.getVideoImgUrl())){
                    throw new ConsumeRuntimeException("视频封面不能为空");
                }
                if(findDynamicInfoDTO.getVideoTime()==null || findDynamicInfoDTO.getVideoTime()<=0){
                    throw new ConsumeRuntimeException("视频时间不能为0");
                }
                if (findDynamicInfoDTO.getFindSourceUrls().size() > 1) {
                    throw new ConsumeRuntimeException("视频最多发布1个");
                }
            }
        }
    }

    public FindDynamicInfo getFindDynamicByFindId(int findId) {
        return findDynamicInfoDao.getFindDynamicByFindId(findId);
    }

    /**
     * 查询发现列表
     * @param userId
     * @param page
     * @param pageSize
     * @param isAudit 审核状态，true 为审核状态，false为关闭审核状态
     * @param channel 渠道号
     * @return
     */
    public List<FindDynamicVO> getFindDynamicInfoList(long userId, int page, int pageSize,
                                                      boolean isAudit, String channel) throws IOException {
        List<FindDynamicVO> list = findDynamicElasticsearch.selectPage(userId,page,pageSize,isAudit,channel);
        return list;
    }

    /**
     * 查询关注列表动态
     * @param userId
     * @param page
     * @param pageSize
     * @param isAudit
     * @param channel
     * @return
     */
    public Map<String,Object> getAttentionFindDynamicInfoList(long userId, Integer page, Integer pageSize, boolean isAudit, String channel) throws IOException {
        Map<String,Object> map = new HashMap<>();
        Set<Long> set = followRedisDao.getMyFollowHost(userId);
        if(set==null||set.size()==0){
            map.put("isFollow",false);
            map.put("message","您还没有关注过我们的寻宝贝");
            map.put("list",new ArrayList<>());
            return map;
        }else{
            List<FindDynamicVO> list = findDynamicElasticsearch.selectAttentionPage(userId,page,pageSize,set,isAudit,channel);
            map.put("isFollow",true);
            map.put("message","成功");
            map.put("list",list);
            return map;
        }
    }

    public List<FindDynamicVO> getVicinityFindDynamicInfoList(long userId, String location,
                                                              Integer page, Integer pageSize, boolean isAudit, String channel) throws IOException {

        List<FindDynamicVO> list = findDynamicElasticsearch.selectVicinityPage(userId,location,page,pageSize,isAudit,channel);

        return list;
    }


    /**
     * 从redis中获取置顶的动态id
     */
    public List<Integer> getFindIds(){
        String key = RedisKeys.DYNAMIC_ISTOP_ZSET.getValue();
        Set<String> set=stringRedisTemplate.opsForZSet().reverseRange(key,0,-1);
        if(set!=null||set.size()>0){
            String target = JSONObject.toJSONString(set);
            List<Integer> list=JSONArray.parseArray(target,Integer.class);
            return list;
        }else{
            return new ArrayList<>();
        }

    }


    /**
     * 个人动态
     * @param userId
     * @param toUserId 目标用户id
     * @param page
     * @param pageSize
     * @param channel
     * @return
     */
    public List<FindDynamicVO> getIndividualInfo(long userId, Long toUserId, Integer page, Integer pageSize, String channel) throws IOException {

        List<FindDynamicVO> list = findDynamicElasticsearch.selectIndividualPage(userId,toUserId,page,pageSize,channel);
        return list;

    }

    /**
     * 详情信息
     * @param findId
     * @param userId 请求用户id
     * @return
     */
    public FindDynamicDetailVO getFindDynamicDetail(int findId, long userId) throws IOException {
        FindDynamicDetailVO findDynamicDetailVO= findDynamicElasticsearch.getFindDynamicInfoByFindId(findId);
        if(findDynamicDetailVO==null){
            throw new  ConsumeRuntimeException("findId不存在");
        }
        findDynamicElasticsearch.getFindDynamicVOByUserInfo(findDynamicDetailVO);
        FindDynamicGiftVO giftInfo = findDynamicGiftInfoElasticsearch.getFindDynamicGiftVO(findId);
        findDynamicDetailVO.setGiftInfo(giftInfo);
        Optional<Long> countFollow = followRedisDao.getMyFollowHostIsExist(userId, findDynamicDetailVO.getUserId());
        if (userId == findDynamicDetailVO.getUserId().longValue()||countFollow.isPresent()) {
            findDynamicDetailVO.setIsFollow(1);
        }
        boolean bl = findDynamicLikeDaoRedis.checkFindDynamicInfoByFindIdAndUserId(findDynamicDetailVO.getFindId(),
                userId);
        if (bl) {
            findDynamicDetailVO.setIsLike(1);
        } else {
            findDynamicDetailVO.setIsLike(2);
        }
        return findDynamicDetailVO;
    }

    public FindDynamicShareVO getFindDynamicShareInfo(Integer findId) throws IOException {
        FindDynamicDetailVO findDynamicDetailVO= findDynamicElasticsearch.getFindDynamicInfoByFindId(findId);
        FindDynamicShareVO findDynamicShareVO = new FindDynamicShareVO();
        findDynamicShareVO.setTitle(findDynamicDetailVO.getFindTitle());
        String content = "";
        if(findDynamicDetailVO.getFindTextContent().length()>FIND_DYNAMIC_CONTENT_LENGTH){
            content = findDynamicDetailVO.getFindTextContent().substring(0,FIND_DYNAMIC_CONTENT_LENGTH)+"...";
        }else{
            content = findDynamicDetailVO.getFindTextContent();
        }
        findDynamicShareVO.setContent(content);
        findDynamicShareVO.setFindId(findId);
        List<FindDynamicSourceVO> dynamicSourceList = findDynamicDetailVO.getSources();

        if (dynamicSourceList.size() > 0) {
            FindDynamicSourceVO dynamicSourceInfo = dynamicSourceList.get(0);
            if (findDynamicDetailVO.getSourceType() == FIND_DYNAMIC_SOURCE_TYPE_IMG.intValue()) {
                findDynamicShareVO.setIcon(dynamicSourceInfo.getFindSourceUrl());
            } else if (findDynamicDetailVO.getSourceType() == FIND_DYNAMIC_SOURCE_TYPE_VOID.intValue()) {
                findDynamicShareVO.setIcon(dynamicSourceInfo.getVideoImgUrl());
            }
        }else{
            findDynamicShareVO.setIcon("");
        }
        Appkey appkey = appKeyService.getAppKeyByKey(FIND_DYNAMIC_SHARE_KEY);
        findDynamicShareVO.setUrl(appkey.getValue()+findId);
        return findDynamicShareVO;
    }
}
